#pragma once
#include <string>
#include <vector>
#include <map>
#include <set>

struct WebPageResult
{
    int doc_id;
    std::string title;
    std::string link;
    std::string abstract;
    double score;
};

class WebPageSearcher
{
public:
    WebPageSearcher();
    void doQuery(const std::string &query, std::vector<WebPageResult> &results);

private:
    void loadInvertedIndex();
    void loadStopWords();
    void loadPages();
    std::vector<std::string> tokenizeQuery(const std::string &query);
    void calculateQueryVector(const std::string &query, std::map<std::string, double> &query_vector);
    double cosineSimilarity(const std::map<std::string, double> &query_vec, const std::map<std::string, double> &doc_vec);
    std::string generateAbstract(const std::string &content, const std::vector<std::string> &keywords);
    WebPageResult getWebPageById(int doc_id);

private:
    std::map<std::string, std::map<int, double>> _invertedIndex;             // 关键字 -> {文档id -> 权重}
    std::map<int, std::tuple<std::string, std::string, std::string>> _pages; // 文档id -> (title, link, content)
    std::set<std::string> _stopWords;
    int _totalDocuments;
    bool _indexLoaded;
};